#include "statefactory.h"

#include "state_2drpg.h"
#include "state_rpgbattle.h"
#include "state_rpgtransition.h"
#include "state_debug.h"

void CStateFactory::Init()
{
  
  m_pCurState = NULL;
  m_bRunning = true;
  m_DPS = 0.0;
  
  m_pStateLine = new CFactoryLine;

  m_pStateLine->Add( new CState2DRPG );
  m_pStateLine->Add( new CStateRPGBattle );
  m_pStateLine->Add( new CStateRPGTransition );
  m_pStateLine->Add( new CStateDebug );
  
}

void CStateFactory::SetGameInterface( CGameInterface * intf )
{
	
	m_pGameInterface = intf;
 
  intf->SetDPSPointer( &m_DPS );

  for( std::vector< CFactoryObject * >::iterator iter = m_pStateLine->begin();
       iter != m_pStateLine->end(); iter++ )
      {
	
	  	CState * s = ( CState * )( *iter );
	  
	  	s->SetGameInterface( intf );
	
      }
  
}

void CStateFactory::SetCurrentState( CState * state )
{
 
  m_pCurState = state;
  
  m_pGameInterface->GetEntityFactory()->SetCurState( state->GetID() );
  
  m_pCurState->Start();
  
  m_pCurState->PreRun();
  
}


void CStateFactory::ParseStateMessage( int msg )
{

	switch( msg )
	{
	
		case 0:
			Log::Debug( "Received exit code" );
			m_bRunning = false;
			break;
			
		case STM_GOTO_2DRPG:
			Log::Debug( "State Change to 2D RPG" );
			SetCurrentState( ( CState * )m_pStateLine->Find( "State2DRPG" ) );
			break;
			
				
		case STM_GOTO_RPGBATTLE:
			Log::Debug( "State Change to RPG Battle" );
			SetCurrentState( ( CState * )m_pStateLine->Find( "StateRPGBattle" ) );
			break;
			
					
		case STM_GOTO_RPGTRANS:
			Log::Debug( "State Change to RPG Battle Transition" );
			SetCurrentState( ( CState * )m_pStateLine->Find( "StateRPGTransition" ) );
			break;

		case STM_GOTO_DEBUG:
			Log::Debug( "State Change to DEBUG" );
			SetCurrentState( ( CState * )m_pStateLine->Find( "StateDebug" ) );
			break;
			
	}
	
}

void CStateFactory::Run()
{
	if( !m_pCurState )
	{
		
		Log::Debug( "Error:  Cur State not set at start of program!" );
		return;
  
	}
	
	Log::Debug( "Entering main loop" );
	
	int CurFrame = 0, LastFrame = 0, NextSecond = 1000 + SDL_GetTicks();
	
	float AvgFPS = 0.0f;
	int FrameCount = 0;

	while( m_bRunning )
	{
		
		if( m_pCurState )
		{
			
			m_pCurState->Input();
			m_pCurState->Think();
			m_pCurState->Draw();
			
			ParseStateMessage( m_pCurState->GetMessage() );
			
		} else
			m_bRunning = false;
			
		CurFrame = SDL_GetTicks();
		
		int fdist = CurFrame - LastFrame;
		
		if( fdist <= 0 )
			fdist = 1;
		
		m_DPS = fdist / 1000.0;
		
		FrameCount++;
		
		if( SDL_GetTicks() > NextSecond )
		{
			
			NextSecond = 1000 + SDL_GetTicks();
			AvgFPS = FrameCount;
			
			if( AvgFPS != FrameCount )
				AvgFPS *= .5f;
			
			FrameCount = 0;
			
		}
		
		LastFrame = CurFrame;

	}
	
	char fps_str[255];
	
	sprintf( fps_str, "Average frames per second was %f", AvgFPS );

	Log::Debug( fps_str );
	
	Log::Debug( "Exiting main loop" );
  
}